home *** CD-ROM | disk | FTP | other *** search
Wrap
//• The following program demonstrates most of the routines created in the //• unit CellusoftAnimations. //• What does the program do? //• The application created by this program will display a window of //• size 300 X 300, with a picture taken from PICT resource ID 130 and //• animate a bunch of rotating eyeballs, each of which will rotate from //• one side of the window to the other continuously. //• The graphics for the eyeballs are from PICT ID 128 and the masks are //• from PICT ID 129. //• In order to gain fuller understanding of the program, you may wish to //• look through the resource file used by the program. //• Animation Project© 1993 Tony Small All Rights Reserved WorldWide //• Many parts of the program do not directly pertain to routines in //• CelluSoftAnimations, but all is thoroughly documented to give further //• insight into graphics, mac design and animation programming. //• This demo was translated to C by Matt Burch - Singularity Software. #include<stdio.h> #include<Windows.h> #define abs(a) ((a)<0?- (a): (a)) #define STACKSPACE 32768L //• used by ToolBoxInit () #define MaxEyes 6 //• the max number of eyes on the screen. //• This shouldn't be bigger than MaxAnimations extern Rect tr[5]; //• an array of temporary rects that we use //• periodically //• These rects are required by the animation routines. struct eyeballs { Rect currentRect, //• Where the eyeball is currently on the screen. lastRect, //• Where the eyeball was on the screen in the //• last animation loop. pictRect; //• Where the picture of the current eyeball //• is located in the Eyeball port. short step; //• Specifies at what stage the eyeball is in its //• movement. Boolean goingLeft; //• If this is true, then the eyeball is moving //• left. If not, then right. }; //• The variable for the main window. WindowPtr mainWindow, testWin; //• The variables for the ports. GrafPtr PureBack, Eyeball, Eyeballmask, offLoad; GDHandle PureBackDevice, EyeballDevice, EyeballmaskDevice, offLoadDevice; //• The array of eyeball records. struct eyeballs eyeBallArray[MaxEyes+1]; //• This function gives a random number from 1 to range. short Randomize (short range) { short rawResult; rawResult = Random (); rawResult = abs (rawResult); return (rawResult % range); } //• This procedure initializes all variables of all eyeball records in the //• eyeballArray. //• It sets the currentRect for each eyeball at a random rect within the //• bounds of the window. //• It sets the step to 1 so each eyeball will start out flat on the screen. //• It randomly sets the goingleft boolean variable. //• It sets the pictRect to the area in the eyeball port that holds the //• flat eyeball picture. void InitializeEyes () { short i; for (i=1;i<=MaxEyes;i++) { eyeBallArray[i].currentRect.left = Randomize (300 - 19); eyeBallArray[i].currentRect.top = Randomize (300 - 10); eyeBallArray[i].currentRect.right = eyeBallArray[i].currentRect.left + 19; eyeBallArray[i].currentRect.bottom = eyeBallArray[i].currentRect.top + 10; eyeBallArray[i].lastRect = eyeBallArray[i].currentRect; eyeBallArray[i].step = 1; if (Randomize (2) == 1) eyeBallArray[i].goingLeft = TRUE; else eyeBallArray[i].goingLeft = FALSE; SetRect (&eyeBallArray[i].pictRect, 0, 0, 19, 10); } } //• These lengthly procedures do not pertain to specific animation routines. //• They merely see at what step the specified eyeball is at, then change //• the step, currentrect, and pictRect accordingly. //• One also very important thing thiese procedure does is set lastRect to //• the currentRect BEFORE the new currentRect is set. void ChangeEye ( short num, short newIn, short left, short top, short right, short bottom, short mleft, short mtop, short mright, short mbottom) { SetRect (&eyeBallArray[num].pictRect, left, top, right, bottom); MoveRect (&eyeBallArray[num].currentRect, mleft, mtop, mright, mbottom); eyeBallArray[num].step = newIn; } void CalcEyeBall (short num) { //• Very important!!!! eyeBallArray[num].lastRect = eyeBallArray[num].currentRect; switch (eyeBallArray[num].step) { case 1: //• Determine which direction the eyeball is going. if (eyeBallArray[num].goingLeft) ChangeEye (num, 20, 0, 11, 19, 23, 0, -2, 0, 0); else ChangeEye (num, 40, 0, 167, 19, 179, 0, -2, 0, 0); break; case 20: ChangeEye (num, 21, 0, 24, 18, 38, 1, -2, 0, 0); break; //• The above for example does the following: //• If the step equals 20, then change the step to 21, change the //• PictRect to coordinates 0,24,18,38, and move the currentRect, one //• pixel over from the left and two pixels up from the top. case 21: ChangeEye (num, 22, 0, 39, 16, 56, 2, -3, 0, 0); break; case 22: ChangeEye (num, 23, 0, 57, 14, 75, 2, -1, 0, 0); break; case 23: ChangeEye (num, 24, 0, 76, 12, 95, 2, -1, 0, 0); break; case 24: ChangeEye (num, 25, 0, 96, 11, 115, 1, 0, 0, 0); break; case 25: ChangeEye (num, 26, 0, 116, 14, 134, 0, 1, 3, 0); break; case 26: ChangeEye (num, 27, 0, 135, 17, 151, 0, 2, 3, 0); break; case 27: ChangeEye (num, 28, 0, 152, 18, 166, 0, 2, 1, 0); break; case 28: ChangeEye (num, 29, 0, 167, 19, 179, 0, 2, 1, 0); break; case 29: //• If the eyeball is at the edge of the screen, //• then change direction. if (eyeBallArray[num].currentRect.right > 300) { ChangeEye (num, 1, 0, 0, 19, 10, 0, 2, 0, 0); eyeBallArray[num].goingLeft = FALSE; } else ChangeEye (num, 1, 0, 0, 19, 10, 0, 2, 0, 0); break; case 40: ChangeEye (num, 41, 0, 152, 18, 166, 0, -2, -1, 0); break; case 41: ChangeEye (num, 42, 0, 135, 17, 151, 0, -2, -1, 0); break; case 42: ChangeEye (num, 43, 0, 116, 14, 134, 0, -2, -3, 0); break; case 43: ChangeEye (num, 44, 0, 96, 11, 115, 0, -1, -3, 0); break; case 44: ChangeEye (num, 45, 0, 76, 12, 95, -1, 0, 0, 0); break; case 45: ChangeEye (num, 46, 0, 57, 14, 75, -2, 1, 0, 0); break; case 46: ChangeEye (num, 47, 0, 39, 16, 56, -2, 1, 0, 0); break; case 47: ChangeEye (num, 48, 0, 24, 18, 38, -2, 3, 0, 0); break; case 48: ChangeEye (num, 49, 0, 11, 19, 23, -1, 2, 0, 0); break; case 49: //• If the eyeball is at the edge of the screen, //• then change direction. if (eyeBallArray[num].currentRect.left < 0) { ChangeEye (num, 1, 0, 0, 19, 10, 0, 2, 0, 0); eyeBallArray[num].goingLeft = true; } else ChangeEye (num, 1, 0, 0, 19, 10, 0, 2, 0, 0); } } //• For each record in the eyeballarray, this procedure calls the above //• procedure, then installs the eyeball into the Animation array with //• setAnimation. void DoTheEyes () { short i; for (i = 1; i <= MaxEyes; i++) { CalcEyeBall (i); SetAnimation (eyeBallArray[i].lastRect, eyeBallArray[i].currentRect, eyeBallArray[i].pictRect, Eyeball, Eyeballmask); //• eyeball and eyeball mask are the two } } //• This function centers a rect on the screen with dimensions of width //• and height. //• This function is called when the Mainwindow is created. void CenterWindow (Rect *r, short width, short height) { short screenHeight, screenWidth, i; //• Get the exact pixel height and width of the screen. screenWidth = screenBits.bounds.right - screenBits.bounds.left; screenHeight = screenBits.bounds.bottom - screenBits.bounds.top; tr[1].top = (screenHeight - height) / 2 + 20; tr[1].left = (screenWidth - width) / 2; SetRect (*&r, tr[1].left, tr[1].top, tr[1].left + width, tr[1].top + height); } //• This function creates a centered window that’s 300x300 pixels in size. void SetUpWindow () { Rect r; CenterWindow (&r, 300, 300); //• center it first mainWindow = NewCWindow (nil, &r, //• then initialize it "\p", TRUE, plainDBox, nil, FALSE, -1L); SetPort (mainWindow); //• Set the port to this new window. ShowWindow (mainWindow); //• Reveal the window. } //• This function creates offscreen ports for our animation. //• See the CellusoftAnimations file for more information. void InitializePorts () { //• Create a color port with PICT ID 130 of dimensions 300 X 300. CreateOffScreen (300, 300, 0, &PureBack, 130); //• Create a blank color port of dimensions 300 X 300. CreateOffScreen (300, 300, 0, &offLoad, -1); //• Create a color port with PICT ID 128 of dimensions 19 X 179. CreateOffScreen (19, 179, 0, &Eyeball, 128); //• Create a black and white port with PICT ID 129 of dimensions 19 X 179. CreateOffScreen (19, 179, 1, &Eyeballmask, 129); } //• This procedure copies the picture from port PureBack to the MainWindow. void DrawBackGround () { Copy (PureBack, mainWindow, PureBack->portRect, mainWindow->portRect); } void WriteMessage (GrafPtr theGraf) { short fontnumber; Str255 thestring; SetPort (theGraf); GetFNum ("\pChicago", &fontnumber); TextFont (fontnumber); TextSize (12); MoveTo (5, 270); DrawString ("\pClick The Mouse To Quit The Demonstration."); } //• This procedure draws the message 'Click the Mouse to Quit the //• Demonstration' at coordinates 5, 270. void DrawMessage () { //• This message is written on both the pureback port and the //• MainWindow so that the eyeballs will not erase the message. WriteMessage (PureBack); //• if the eyballs and the message happens to collide. WriteMessage (mainWindow); } void main () { ToolBoxInit (); //• Initialize the Mac GetDateTime (&randSeed); //• Initialize the random number generator in the Macintosh system. HideCursor (); //• Hide the cursor. SetUpWindow (); //• Create the window. InitializePorts (); //• Create the ports. DrawBackGround (); //• Draw the picture onto the window InitializeEyes (); //• Initialize the variables for the eyeballs. SetPort (mainWindow); //• Set the current port to the main window. DrawMessage (); //• Draw the message onto the screen. while (!Button ()) //• While the mouse button is not down, perform the following loop. { SetPort (mainWindow); //• make sure we’re drawing to the main window InitAnimations (); //• Reset the animations. DoTheEyes (); //• Move the eyes and load them into the animation array. AnimateArray (PureBack, offLoad, mainWindow); //• Animate the animation array. } //• The preserved background graphic is in the port pureback. //• The port to be used for workspace is offLoad. //• The port to draw the animations to is the window MainWindow. ShowCursor (); //• Show the cursor before exiting. } ToolBoxInit () //• this initializes the Mac’s Toolbox { SetApplLimit (GetApplLimit () - (STACKSPACE - DefltStack)); InitGraf (&thePort); InitCursor (); InitFonts (); InitWindows (); InitMenus (); TEInit (); InitDialogs (0L); InitCursor (); MaxApplZone (); }